﻿using System;
using System.Text;
using HslCommunication.BasicFramework;

namespace HslCommunication.Profinet.Panasonic
{
	/// <summary>
	/// 松下PLC的辅助类，提供了基本的辅助方法，用于解析地址，计算校验和，创建报文<br />
	/// The auxiliary class of Panasonic PLC provides basic auxiliary methods for parsing addresses, calculating checksums, and creating messages
	/// </summary>
	// Token: 0x02000052 RID: 82
	public class PanasonicHelper
	{
		// Token: 0x060006C8 RID: 1736 RVA: 0x00022B40 File Offset: 0x00020D40
		private static string CalculateCrc(StringBuilder sb)
		{
			byte b = (byte)sb[0];
			for (int i = 1; i < sb.Length; i++)
			{
				b ^= (byte)sb[i];
			}
			return SoftBasic.ByteToHexString(new byte[]
			{
				b
			});
		}

		/// <summary>
		/// 位地址转换方法，101等同于10.1等同于10*16+1=161<br />
		/// Bit address conversion method, 101 is equivalent to 10.1 is equivalent to 10 * 16 + 1 = 161
		/// </summary>
		/// <param name="address">地址信息</param>
		/// <returns>实际的位地址信息</returns>
		// Token: 0x060006C9 RID: 1737 RVA: 0x00022B90 File Offset: 0x00020D90
		public static int CalculateComplexAddress(string address)
		{
			bool flag = address.IndexOf(".") < 0;
			int num;
			if (flag)
			{
				bool flag2 = address.Length == 1;
				if (flag2)
				{
					num = Convert.ToInt32(address, 16);
				}
				else
				{
					num = Convert.ToInt32(address.Substring(0, address.Length - 1)) * 16 + Convert.ToInt32(address.Substring(address.Length - 1), 16);
				}
			}
			else
			{
				num = Convert.ToInt32(address.Substring(0, address.IndexOf("."))) * 16;
				string text = address.Substring(address.IndexOf(".") + 1);
				bool flag3 = text.Contains("A") || text.Contains("B") || text.Contains("C") || text.Contains("D") || text.Contains("E") || text.Contains("F");
				if (flag3)
				{
					num += Convert.ToInt32(text, 16);
				}
				else
				{
					num += Convert.ToInt32(text);
				}
			}
			return num;
		}

		/// <summary>
		/// 解析数据地址，解析出地址类型，起始地址<br />
		/// Parse the data address, resolve the address type, start address
		/// </summary>
		/// <param name="address">数据地址</param>
		/// <returns>解析出地址类型，起始地址</returns>
		// Token: 0x060006CA RID: 1738 RVA: 0x00022CA8 File Offset: 0x00020EA8
		public static OperateResult<string, int> AnalysisAddress(string address)
		{
			OperateResult<string, int> operateResult = new OperateResult<string, int>();
			try
			{
				operateResult.Content2 = 0;
				bool flag = address.StartsWith("IX") || address.StartsWith("ix");
				if (flag)
				{
					operateResult.Content1 = "IX";
					operateResult.Content2 = int.Parse(address.Substring(2));
				}
				else
				{
					bool flag2 = address.StartsWith("IY") || address.StartsWith("iy");
					if (flag2)
					{
						operateResult.Content1 = "IY";
						operateResult.Content2 = int.Parse(address.Substring(2));
					}
					else
					{
						bool flag3 = address.StartsWith("ID") || address.StartsWith("id");
						if (flag3)
						{
							operateResult.Content1 = "ID";
							operateResult.Content2 = int.Parse(address.Substring(2));
						}
						else
						{
							bool flag4 = address.StartsWith("SR") || address.StartsWith("sr");
							if (flag4)
							{
								operateResult.Content1 = "SR";
								operateResult.Content2 = PanasonicHelper.CalculateComplexAddress(address.Substring(2));
							}
							else
							{
								bool flag5 = address.StartsWith("LD") || address.StartsWith("ld");
								if (flag5)
								{
									operateResult.Content1 = "LD";
									operateResult.Content2 = int.Parse(address.Substring(2));
								}
								else
								{
									bool flag6 = address[0] == 'X' || address[0] == 'x';
									if (flag6)
									{
										operateResult.Content1 = "X";
										operateResult.Content2 = PanasonicHelper.CalculateComplexAddress(address.Substring(1));
									}
									else
									{
										bool flag7 = address[0] == 'Y' || address[0] == 'y';
										if (flag7)
										{
											operateResult.Content1 = "Y";
											operateResult.Content2 = PanasonicHelper.CalculateComplexAddress(address.Substring(1));
										}
										else
										{
											bool flag8 = address[0] == 'R' || address[0] == 'r';
											if (flag8)
											{
												operateResult.Content1 = "R";
												operateResult.Content2 = PanasonicHelper.CalculateComplexAddress(address.Substring(1));
											}
											else
											{
												bool flag9 = address[0] == 'T' || address[0] == 't';
												if (flag9)
												{
													operateResult.Content1 = "T";
													operateResult.Content2 = int.Parse(address.Substring(1));
												}
												else
												{
													bool flag10 = address[0] == 'C' || address[0] == 'c';
													if (flag10)
													{
														operateResult.Content1 = "C";
														operateResult.Content2 = int.Parse(address.Substring(1));
													}
													else
													{
														bool flag11 = address[0] == 'L' || address[0] == 'l';
														if (flag11)
														{
															operateResult.Content1 = "L";
															operateResult.Content2 = PanasonicHelper.CalculateComplexAddress(address.Substring(1));
														}
														else
														{
															bool flag12 = address[0] == 'D' || address[0] == 'd';
															if (flag12)
															{
																operateResult.Content1 = "D";
																operateResult.Content2 = int.Parse(address.Substring(1));
															}
															else
															{
																bool flag13 = address[0] == 'F' || address[0] == 'f';
																if (flag13)
																{
																	operateResult.Content1 = "F";
																	operateResult.Content2 = int.Parse(address.Substring(1));
																}
																else
																{
																	bool flag14 = address[0] == 'S' || address[0] == 's';
																	if (flag14)
																	{
																		operateResult.Content1 = "S";
																		operateResult.Content2 = int.Parse(address.Substring(1));
																	}
																	else
																	{
																		bool flag15 = address[0] == 'K' || address[0] == 'k';
																		if (!flag15)
																		{
																			throw new Exception(StringResources.Language.NotSupportedDataType);
																		}
																		operateResult.Content1 = "K";
																		operateResult.Content2 = int.Parse(address.Substring(1));
																	}
																}
															}
														}
													}
												}
											}
										}
									}
								}
							}
						}
					}
				}
			}
			catch (Exception ex)
			{
				operateResult.Message = ex.Message;
				return operateResult;
			}
			operateResult.IsSuccess = true;
			return operateResult;
		}

		/// <summary>
		/// 创建读取离散触点的报文指令<br />
		/// Create message instructions for reading discrete contacts
		/// </summary>
		/// <param name="station">站号信息</param>
		/// <param name="address">地址信息</param>
		/// <returns>包含是否成功的结果对象</returns>
		// Token: 0x060006CB RID: 1739 RVA: 0x00023124 File Offset: 0x00021324
		public static OperateResult<byte[]> BuildReadOneCoil(byte station, string address)
		{
			bool flag = address == null;
			OperateResult<byte[]> result;
			if (flag)
			{
				result = new OperateResult<byte[]>("address is not allowed null");
			}
			else
			{
				bool flag2 = address.Length < 1 || address.Length > 8;
				if (flag2)
				{
					result = new OperateResult<byte[]>("length must be 1-8");
				}
				else
				{
					StringBuilder stringBuilder = new StringBuilder("%");
					stringBuilder.Append(station.ToString("X2"));
					stringBuilder.Append("#RCS");
					OperateResult<string, int> operateResult = PanasonicHelper.AnalysisAddress(address);
					bool flag3 = !operateResult.IsSuccess;
					if (flag3)
					{
						result = OperateResult.CreateFailedResult<byte[]>(operateResult);
					}
					else
					{
						stringBuilder.Append(operateResult.Content1);
						bool flag4 = operateResult.Content1 == "X" || operateResult.Content1 == "Y" || operateResult.Content1 == "R" || operateResult.Content1 == "L";
						if (flag4)
						{
							stringBuilder.Append((operateResult.Content2 / 16).ToString("D3"));
							stringBuilder.Append((operateResult.Content2 % 16).ToString("X1"));
						}
						else
						{
							bool flag5 = operateResult.Content1 == "T" || operateResult.Content1 == "C";
							if (!flag5)
							{
								return new OperateResult<byte[]>(StringResources.Language.NotSupportedDataType);
							}
							stringBuilder.Append("0");
							stringBuilder.Append(operateResult.Content2.ToString("D3"));
						}
						stringBuilder.Append(PanasonicHelper.CalculateCrc(stringBuilder));
						stringBuilder.Append('\r');
						result = OperateResult.CreateSuccessResult<byte[]>(Encoding.ASCII.GetBytes(stringBuilder.ToString()));
					}
				}
			}
			return result;
		}

		/// <summary>
		/// 创建写入离散触点的报文指令<br />
		/// Create message instructions to write discrete contacts
		/// </summary>
		/// <param name="station">站号信息</param>
		/// <param name="address">地址信息</param>
		/// <param name="value">bool值数组</param>
		/// <returns>包含是否成功的结果对象</returns>
		// Token: 0x060006CC RID: 1740 RVA: 0x000232F8 File Offset: 0x000214F8
		public static OperateResult<byte[]> BuildWriteOneCoil(byte station, string address, bool value)
		{
			StringBuilder stringBuilder = new StringBuilder("%");
			stringBuilder.Append(station.ToString("X2"));
			stringBuilder.Append("#WCS");
			OperateResult<string, int> operateResult = PanasonicHelper.AnalysisAddress(address);
			bool flag = !operateResult.IsSuccess;
			OperateResult<byte[]> result;
			if (flag)
			{
				result = OperateResult.CreateFailedResult<byte[]>(operateResult);
			}
			else
			{
				stringBuilder.Append(operateResult.Content1);
				bool flag2 = operateResult.Content1 == "X" || operateResult.Content1 == "Y" || operateResult.Content1 == "R" || operateResult.Content1 == "L";
				if (flag2)
				{
					stringBuilder.Append((operateResult.Content2 / 16).ToString("D3"));
					stringBuilder.Append((operateResult.Content2 % 16).ToString("X1"));
				}
				else
				{
					bool flag3 = operateResult.Content1 == "T" || operateResult.Content1 == "C";
					if (!flag3)
					{
						return new OperateResult<byte[]>(StringResources.Language.NotSupportedDataType);
					}
					stringBuilder.Append("0");
					stringBuilder.Append(operateResult.Content2.ToString("D3"));
				}
				stringBuilder.Append(value ? '1' : '0');
				stringBuilder.Append(PanasonicHelper.CalculateCrc(stringBuilder));
				stringBuilder.Append('\r');
				result = OperateResult.CreateSuccessResult<byte[]>(Encoding.ASCII.GetBytes(stringBuilder.ToString()));
			}
			return result;
		}

		/// <summary>
		/// 创建批量读取触点的报文指令<br />
		/// Create message instructions for batch reading contacts
		/// </summary>
		/// <param name="station">站号信息</param>
		/// <param name="address">地址信息</param>
		/// <param name="length">数据长度</param>
		/// <returns>包含是否成功的结果对象</returns>
		// Token: 0x060006CD RID: 1741 RVA: 0x00023494 File Offset: 0x00021694
		public static OperateResult<byte[]> BuildReadCommand(byte station, string address, ushort length)
		{
			bool flag = address == null;
			OperateResult<byte[]> result;
			if (flag)
			{
				result = new OperateResult<byte[]>(StringResources.Language.PanasonicAddressParameterCannotBeNull);
			}
			else
			{
				OperateResult<string, int> operateResult = PanasonicHelper.AnalysisAddress(address);
				bool flag2 = !operateResult.IsSuccess;
				if (flag2)
				{
					result = OperateResult.CreateFailedResult<byte[]>(operateResult);
				}
				else
				{
					StringBuilder stringBuilder = new StringBuilder("%");
					stringBuilder.Append(station.ToString("X2"));
					stringBuilder.Append("#");
					bool flag3 = operateResult.Content1 == "X" || operateResult.Content1 == "Y" || operateResult.Content1 == "R" || operateResult.Content1 == "L";
					if (flag3)
					{
						stringBuilder.Append("RCC");
						stringBuilder.Append(operateResult.Content1);
						int num = operateResult.Content2 / 16;
						int num2 = (operateResult.Content2 + (int)length - 1) / 16;
						stringBuilder.Append(num.ToString("D4"));
						stringBuilder.Append(num2.ToString("D4"));
					}
					else
					{
						bool flag4 = operateResult.Content1 == "D" || operateResult.Content1 == "LD" || operateResult.Content1 == "F";
						if (flag4)
						{
							stringBuilder.Append("RD");
							stringBuilder.Append(operateResult.Content1.Substring(0, 1));
							stringBuilder.Append(operateResult.Content2.ToString("D5"));
							stringBuilder.Append((operateResult.Content2 + (int)length - 1).ToString("D5"));
						}
						else
						{
							bool flag5 = operateResult.Content1 == "IX" || operateResult.Content1 == "IY" || operateResult.Content1 == "ID";
							if (flag5)
							{
								stringBuilder.Append("RD");
								stringBuilder.Append(operateResult.Content1);
								stringBuilder.Append("000000000");
							}
							else
							{
								bool flag6 = operateResult.Content1 == "C" || operateResult.Content1 == "T";
								if (!flag6)
								{
									return new OperateResult<byte[]>(StringResources.Language.NotSupportedDataType);
								}
								stringBuilder.Append("RS");
								stringBuilder.Append(operateResult.Content2.ToString("D4"));
								stringBuilder.Append((operateResult.Content2 + (int)length - 1).ToString("D4"));
							}
						}
					}
					stringBuilder.Append(PanasonicHelper.CalculateCrc(stringBuilder));
					stringBuilder.Append('\r');
					result = OperateResult.CreateSuccessResult<byte[]>(Encoding.ASCII.GetBytes(stringBuilder.ToString()));
				}
			}
			return result;
		}

		/// <summary>
		/// 创建批量读取触点的报文指令<br />
		/// Create message instructions for batch reading contacts
		/// </summary>
		/// <param name="station">设备站号</param>
		/// <param name="address">地址信息</param>
		/// <param name="values">数据值</param>
		/// <returns>包含是否成功的结果对象</returns>
		// Token: 0x060006CE RID: 1742 RVA: 0x00023778 File Offset: 0x00021978
		public static OperateResult<byte[]> BuildWriteCommand(byte station, string address, byte[] values)
		{
			bool flag = address == null;
			OperateResult<byte[]> result;
			if (flag)
			{
				result = new OperateResult<byte[]>(StringResources.Language.PanasonicAddressParameterCannotBeNull);
			}
			else
			{
				OperateResult<string, int> operateResult = PanasonicHelper.AnalysisAddress(address);
				bool flag2 = !operateResult.IsSuccess;
				if (flag2)
				{
					result = OperateResult.CreateFailedResult<byte[]>(operateResult);
				}
				else
				{
					values = SoftBasic.ArrayExpandToLengthEven<byte>(values);
					short num = (short)(values.Length / 2);
					StringBuilder stringBuilder = new StringBuilder("%");
					stringBuilder.Append(station.ToString("X2"));
					stringBuilder.Append("#");
					bool flag3 = operateResult.Content1 == "X" || operateResult.Content1 == "Y" || operateResult.Content1 == "R" || operateResult.Content1 == "L";
					if (flag3)
					{
						stringBuilder.Append("WCC");
						stringBuilder.Append(operateResult.Content1);
						int num2 = operateResult.Content2 / 16;
						int num3 = (operateResult.Content2 + values.Length * 8 - 1) / 16;
						stringBuilder.Append(num2.ToString("D4"));
						stringBuilder.Append((num3 - num2 + 1).ToString("D4"));
					}
					else
					{
						bool flag4 = operateResult.Content1 == "D" || operateResult.Content1 == "LD" || operateResult.Content1 == "F";
						if (flag4)
						{
							stringBuilder.Append("WD");
							stringBuilder.Append(operateResult.Content1.Substring(0, 1));
							stringBuilder.Append(operateResult.Content2.ToString("D5"));
							stringBuilder.Append((operateResult.Content2 + (int)num - 1).ToString("D5"));
						}
						else
						{
							bool flag5 = operateResult.Content1 == "IX" || operateResult.Content1 == "IY" || operateResult.Content1 == "ID";
							if (flag5)
							{
								stringBuilder.Append("WD");
								stringBuilder.Append(operateResult.Content1);
								stringBuilder.Append(operateResult.Content2.ToString("D9"));
								stringBuilder.Append((operateResult.Content2 + (int)num - 1).ToString("D9"));
							}
							else
							{
								bool flag6 = operateResult.Content1 == "C" || operateResult.Content1 == "T";
								if (flag6)
								{
									stringBuilder.Append("WS");
									stringBuilder.Append(operateResult.Content2.ToString("D4"));
									stringBuilder.Append((operateResult.Content2 + (int)num - 1).ToString("D4"));
								}
							}
						}
					}
					stringBuilder.Append(SoftBasic.ByteToHexString(values));
					stringBuilder.Append(PanasonicHelper.CalculateCrc(stringBuilder));
					stringBuilder.Append('\r');
					result = OperateResult.CreateSuccessResult<byte[]>(Encoding.ASCII.GetBytes(stringBuilder.ToString()));
				}
			}
			return result;
		}

		/// <summary>
		/// 检查从PLC反馈的数据，并返回正确的数据内容<br />
		/// Check the data feedback from the PLC and return the correct data content
		/// </summary>
		/// <param name="response">反馈信号</param>
		/// <returns>是否成功的结果信息</returns>
		// Token: 0x060006CF RID: 1743 RVA: 0x00023AA0 File Offset: 0x00021CA0
		public static OperateResult<byte[]> ExtraActualData(byte[] response)
		{
			bool flag = response.Length < 9;
			OperateResult<byte[]> result;
			if (flag)
			{
				result = new OperateResult<byte[]>(StringResources.Language.PanasonicReceiveLengthMustLargerThan9);
			}
			else
			{
				bool flag2 = response[3] == 36;
				if (flag2)
				{
					byte[] array = new byte[response.Length - 9];
					bool flag3 = array.Length != 0;
					if (flag3)
					{
						Array.Copy(response, 6, array, 0, array.Length);
						array = SoftBasic.HexStringToBytes(Encoding.ASCII.GetString(array));
					}
					result = OperateResult.CreateSuccessResult<byte[]>(array);
				}
				else
				{
					bool flag4 = response[3] == 33;
					if (flag4)
					{
						int err = int.Parse(Encoding.ASCII.GetString(response, 4, 2));
						result = new OperateResult<byte[]>(err, PanasonicHelper.GetErrorDescription(err));
					}
					else
					{
						result = new OperateResult<byte[]>(StringResources.Language.UnknownError);
					}
				}
			}
			return result;
		}

		/// <summary>
		/// 检查从PLC反馈的数据，并返回正确的数据内容<br />
		/// Check the data feedback from the PLC and return the correct data content
		/// </summary>
		/// <param name="response">反馈信号</param>
		/// <returns>是否成功的结果信息</returns>
		// Token: 0x060006D0 RID: 1744 RVA: 0x00023B64 File Offset: 0x00021D64
		public static OperateResult<bool> ExtraActualBool(byte[] response)
		{
			bool flag = response.Length < 9;
			OperateResult<bool> result;
			if (flag)
			{
				result = new OperateResult<bool>(StringResources.Language.PanasonicReceiveLengthMustLargerThan9);
			}
			else
			{
				bool flag2 = response[3] == 36;
				if (flag2)
				{
					result = OperateResult.CreateSuccessResult<bool>(response[6] == 49);
				}
				else
				{
					bool flag3 = response[3] == 33;
					if (flag3)
					{
						int err = int.Parse(Encoding.ASCII.GetString(response, 4, 2));
						result = new OperateResult<bool>(err, PanasonicHelper.GetErrorDescription(err));
					}
					else
					{
						result = new OperateResult<bool>(StringResources.Language.UnknownError);
					}
				}
			}
			return result;
		}

		/// <summary>
		/// 根据错误码获取到错误描述文本<br />
		/// Get the error description text according to the error code
		/// </summary>
		/// <param name="err">错误代码</param>
		/// <returns>字符信息</returns>
		// Token: 0x060006D1 RID: 1745 RVA: 0x00023BF0 File Offset: 0x00021DF0
		public static string GetErrorDescription(int err)
		{
			switch (err)
			{
			case 20:
				return StringResources.Language.PanasonicMewStatus20;
			case 21:
				return StringResources.Language.PanasonicMewStatus21;
			case 22:
				return StringResources.Language.PanasonicMewStatus22;
			case 23:
				return StringResources.Language.PanasonicMewStatus23;
			case 24:
				return StringResources.Language.PanasonicMewStatus24;
			case 25:
				return StringResources.Language.PanasonicMewStatus25;
			case 26:
				return StringResources.Language.PanasonicMewStatus26;
			case 27:
				return StringResources.Language.PanasonicMewStatus27;
			case 28:
				return StringResources.Language.PanasonicMewStatus28;
			case 29:
				return StringResources.Language.PanasonicMewStatus29;
			case 30:
				return StringResources.Language.PanasonicMewStatus30;
			case 40:
				return StringResources.Language.PanasonicMewStatus40;
			case 41:
				return StringResources.Language.PanasonicMewStatus41;
			case 42:
				return StringResources.Language.PanasonicMewStatus42;
			case 43:
				return StringResources.Language.PanasonicMewStatus43;
			case 50:
				return StringResources.Language.PanasonicMewStatus50;
			case 51:
				return StringResources.Language.PanasonicMewStatus51;
			case 52:
				return StringResources.Language.PanasonicMewStatus52;
			case 53:
				return StringResources.Language.PanasonicMewStatus53;
			case 60:
				return StringResources.Language.PanasonicMewStatus60;
			case 61:
				return StringResources.Language.PanasonicMewStatus61;
			case 62:
				return StringResources.Language.PanasonicMewStatus62;
			case 63:
				return StringResources.Language.PanasonicMewStatus63;
			case 65:
				return StringResources.Language.PanasonicMewStatus65;
			case 66:
				return StringResources.Language.PanasonicMewStatus66;
			case 67:
				return StringResources.Language.PanasonicMewStatus67;
			}
			return StringResources.Language.UnknownError;
		}
	}
}
